package com.ming.core.parser.graph;

import com.ming.core.parser.entity.node.Node;
import com.yomahub.liteflow.builder.el.ELBus;
import com.yomahub.liteflow.builder.el.ELWrapper;
import com.yomahub.liteflow.builder.el.ThenELWrapper;
import com.yomahub.liteflow.builder.el.WhenELWrapper;

import java.util.ArrayList;
import java.util.List;

public class GraphToEL {

    public static ELWrapper toEL(Graph graph) {
        List<List<List<Node>>> groupPaths = graph.getGroupPaths();
        //只有一条路径
        if(groupPaths.size() == 1){
            ThenELWrapper thenELWrapper = ELBus.then();
            processSegments(thenELWrapper, graph, groupPaths.get(0));
            return thenELWrapper;
        }else if(groupPaths.size() > 1){//多条路径
            WhenELWrapper whenELWrapper = ELBus.when();
            for (List<List<Node>> paths : groupPaths){
                ThenELWrapper thenELWrapper = ELBus.then();
                processSegments(thenELWrapper, graph, paths);
                whenELWrapper.when(thenELWrapper);
            }
            return whenELWrapper;
        }
        return ELBus.then();
    }

    //处理分段节点
    private static void processSegments(ThenELWrapper thenELWrapper, Graph graph, List<List<Node>> allPaths){
        List<Node> segmentationPoints = GraphUtil.findSegmentationPoints(allPaths, graph.getNodes());
        List<List<Node>> processSegments = GraphUtil.getProcessSegments(allPaths, segmentationPoints);
        List<List<Node>> segments = GraphUtil.mergeSingleElementSegments(processSegments);
        for (List<Node> items : segments){
            flow(thenELWrapper, graph, items);
        }
    }

    private static void flow(ThenELWrapper thenELWrapper, Graph graph, List<Node> nodes){
        List<List<Node>> allPathByNodes = GraphUtil.findAllPathByNodes(nodes, graph);
        if(allPathByNodes.size() == 1){
            List<Node> path = allPathByNodes.get(0);
            for (Node node : path){
                thenELWrapper.then(node.getData().getId());
            }
        }else if(allPathByNodes.size() > 1){
            WhenELWrapper whenELWrapper = ELBus.when();
            List<List<List<Node>>> grouped = GraphUtil.groupPathsByIntersection(allPathByNodes);
            if(grouped.size() > 1){
                for (List<List<Node>> itemList : grouped){
                    if(itemList.size() == 1){
                        whenELWrapper.when(itemList.get(0).get(0).getData().getId());
                    }else{
                        List<Node> startSameNode = GraphUtil.startSameNode(itemList);
                        if(!startSameNode.isEmpty()){
                            ThenELWrapper thenELWrapper1 = ELBus.then();
                            thenELWrapper1.then(startSameNode.get(0).getData().getId());
                            flow(thenELWrapper1, graph, GraphUtil.excludeSameNode(itemList,startSameNode));
                            whenELWrapper.when(thenELWrapper1);
                        }else{
                            ThenELWrapper thenELWrapper1 = ELBus.then();
                            flow(thenELWrapper1, graph, GraphUtil.excludeSameNode(itemList,new ArrayList<>()));
                            whenELWrapper.when(thenELWrapper1);
                        }
                    }
                }
            }else{
                for (List<Node> itemList : allPathByNodes){
                    if(itemList.size() == 1){
                        whenELWrapper.when(itemList.get(0).getData().getId());
                    }else{
                        ThenELWrapper thenELWrapper1 = ELBus.then();
                        flow(thenELWrapper1, graph, itemList);
                        whenELWrapper.when(thenELWrapper1);
                    }
                }
            }
            thenELWrapper.then(whenELWrapper);
        }
    }
}
